import numpy as np
import time
import pyopencl as cl
import verbose
import configuration as config
import pair 
import potential
import neighbor

ctx = cl.create_some_context()
que = cl.CommandQueue(ctx)
#opencl_index=[0,0]
#platform = cl.get_platforms()[opencl_index[0]]
#device = platform.get_devices()[opencl_index[1]]
#ctx = cl.Context([device]) 
#que = cl.CommandQueue(ctx)
v = verbose.Verbose()
v.set_verbose_level(12)

cfg = config.Configuration()
cfg.read_lammps_data('lj.data_32k.gz',datatype='pair')

cfg.init_device(ctx)
cfg.copy_to_device(que)
#cfg.get_from_device(que)
#print 'box_l, box_p:'
#print cfg.box_l
#print cfg.box_p

###---change to a small size###
#cfg.n_atoms /= 10 #for test
###

#print 'r_t[0:2]:'
#print cfg.r_t[0:2]
#print 'f_e[0:2]:'
#print cfg.f_e[0:2]

pots = potential.Potential(ctx)
neig = neighbor.Neighbor(cl_file='neighbor.cl',context=ctx)
print '--to-gen-grid'
t0 = time.time()
neig.create_grid_nei(que,cfg)
print 'create-nei(grid) time:', time.time()-t0
#print 'grid[0:5]:'
#print neig.grid[0,0,0:5]
#print 'n_grid[0:5]:'
#print neig.n_grid[0,0,0:5]
#print 'by_grid:'
#print 'n_neigh[0:2]:'
#print neig.n_nei
#print 'neigh[0:2]:'
#print neig.nei

t0 = time.time()
#neig.create_slow(que,cfg)
print 'create-nei(slow) time:', time.time()-t0
#print 'by_slow:'
print 'n_neigh[0:2]:'
print neig.n_nei
print 'neigh[0:2]:'
print neig.nei

print 'max neighs/atom',np.max(neig.n_nei)
print 'ave neighs/atom',np.sum(neig.n_nei)/cfg.n_atoms

#t0 = time.time()
#neig.sort_host(que,cfg)
#print 'sort on host time:', time.time()-t0
#neig.create_grid_nei(que,cfg)

lj = pair.Pair('pair_lj_cut','pair_lj_cut.cl',None,ctx)
pots.add_potential(lj)

nloop = 100
t0 = time.time()
for i in range(nloop):
    pots.cal_f_e_vir_all(que,cfg,neig)
cfg.get_from_device(que)
t1 = time.time()
#lj.read_parameter(None)
print 'f_e[0:10]:'
print cfg.f_e[0:10]
print nloop,' X cal_force(neigh) time:',t1-t0
print 'aver force_en:',sum(cfg.f_e)/cfg.n_atoms
print '-------'

nloop = 1
t0 = time.time()
for i in range(nloop):
    pots.cal_f_e_slow(que,cfg)
cfg.get_from_device(que)
t1 = time.time()
#lj.read_parameter(None)
print 'f_e[0:10]:'
print cfg.f_e[0:10]
print nloop,' X cal_force(n2) time:',t1-t0
print 'aver force_en:',sum(cfg.f_e)/cfg.n_atoms

nstep = 100
import verlet
ver = verlet.Verlet('verlet',ctx)
t0 = time.time()
ver.nve(que,cfg,neig,pots,nstep,0.01)
cfg.get_from_device(que)
t1 = time.time()
print 'f_e[0:10]:'
print cfg.f_e[0:10]
print nstep,' X verlet NVE time:',t1-t0
print 'aver force_en:',sum(cfg.f_e)/cfg.n_atoms



